﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Navigation;
using System.Windows.Media;

namespace Robert.TwitBy.Converters
{
    class TweetStatusConverter: MarkupExtension, IMultiValueConverter
    {
        const string HttpMarker = "http://";
        private static Binding _mentionBinding = new Binding { ElementName="me", Path = new PropertyPath("DataContext.MentionCommand") };
        private static Binding _hyperlinkBinding = new Binding { ElementName = "me", Path = new PropertyPath("DataContext.HyperlinkCommand") };
        private static Binding _hashtagBinding = new Binding { ElementName = "me", Path = new PropertyPath("DataContext.HashtagCommand") };

        [DebuggerStepThrough]
        public object Convert(object[] value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var Status = value[0] as string;
            var ID = value[1] as string;
            Status = System.Web.HttpUtility.HtmlDecode(Status).ToString();

            var textBlock = new TextBlock()
            {
                TextWrapping = System.Windows.TextWrapping.Wrap,
            };
            #region Check to see if we have mentions hashtags or links

            int i = 0, j = 0;
            while(i<Status.Length)
            {
                var phrase = string.Empty;
                if (Status[i] == '@')//we have a mention
                {
                    j = i;
                    phrase += Status[i];
                    i++;
                    while(i<Status.Length && (char.IsLetterOrDigit(Status[i]) || Status[i]=='_'))
                    {
                        phrase += Status[i];
                        i++;
                    }
                    if (phrase.Length > 1)
                    {
                        textBlock.Inlines.Add(CreateMentionsLink(phrase));
                        phrase = string.Empty;
                    }
                    else
                    {
                        textBlock.Inlines.Add(Status[j].ToString());
                    }
                    continue;
                }
                else
                    if (Status[i] == '#')//we have hashtag
                    {
                        j = i;
                        phrase += Status[i];
                        i++;
                        while (i < Status.Length && (char.IsLetterOrDigit(Status[i]) || Status[i] == '_'))
                        {
                            phrase += Status[i];
                            i++;
                        }
                        if (phrase.Length > 1)
                        {
                            textBlock.Inlines.Add(CreateHashtagLink(phrase));
                            phrase = string.Empty;
                        }
                        else
                        {
                            textBlock.Inlines.Add(Status[j].ToString());
                        }
                        continue;
                    }
                if (Status.Length - i > HttpMarker.Length && Status.Substring(i, 7) == HttpMarker)//we have a link
                {
                    phrase += Status.Substring(i, 7);
                    i += 7;
                    while (i<Status.Length && !char.IsWhiteSpace(Status[i]))
                    {
                        phrase += Status[i];
                        i++;
                    }
                    textBlock.Inlines.Add(CreateLink(phrase));
                    phrase = string.Empty;
                }
                if(i<Status.Length)
                    textBlock.Inlines.Add(Status[i].ToString());
                i++;
            }

            #endregion

            if (ID == "TwitBy" || ID == "Mention" || ID == "Direct" || ID == "Home" || ID == "Sent")
                textBlock.Foreground = new SolidColorBrush(Colors.White);
            else
                textBlock.Foreground = new SolidColorBrush(Colors.Black);

            return textBlock;
        }

        private static Hyperlink CreateMentionsLink(string phrase)
        {
            var link = new Hyperlink();
            var s = phrase;

            link.Inlines.Add(phrase);
            link.TextDecorations = null;
            link.Foreground = new SolidColorBrush(Colors.DarkOliveGreen);
            link.SetBinding(Hyperlink.CommandProperty, _mentionBinding);
            link.ToolTip = "Add " + phrase + " to your tweet message.";
            link.CommandParameter = phrase;

            return link;
        }

        private static Hyperlink CreateHashtagLink(string phrase)
        {
            var link = new Hyperlink();
            link.TextDecorations = null;
            link.Foreground = new SolidColorBrush(Colors.DarkSlateBlue);
            link.Inlines.Add(phrase);
            link.SetBinding(Hyperlink.CommandProperty, _hashtagBinding);
            link.ToolTip = "Search for " + phrase + ". Opens a new twitter search in default browser.";
            
            var param = "http://search.twitter.com/search?q=" + System.Web.HttpUtility.UrlEncode(phrase);
            link.CommandParameter = param;

            return link;
        }

        private static Hyperlink CreateLink(string phrase)
        {
            var link = new Hyperlink();
            link.ToolTip = "Open link in default browser.";
            link.TextDecorations = null;
            link.Foreground = new SolidColorBrush(Colors.DodgerBlue);
            link.Inlines.Add(phrase);
            link.SetBinding(Hyperlink.CommandProperty, _hyperlinkBinding);
            link.CommandParameter = phrase;

            return link;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return this;
        }
    }
}
